﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace Snake.Model
{
    class Client
    {
        private Mutex mu = new Mutex();
        private NetworkStream clientStream;
        private Thread Listen;
        private Thread sender;
        private string NameOtherPlayer;
        private TcpClient client;
        private snake snakeRecu;
        private snake snake  = new snake();
        private Boolean recu = false;



        public snake SnakeRecu
        {
            get { return snakeRecu; }
        }

        public Boolean Recu
        {
            get { return this.recu; }
            set { this.recu = value; }
        }

        public string nameotherplayer
        {
            get { return this.NameOtherPlayer; }
            set { this.NameOtherPlayer = value; }
        }

        public Client(string ip)
        {

            
            //déclaration client tcp
            this.client = new TcpClient();



            //mise en place des paramêtres. Ici il faudra modifier l'addresse Ip
            IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse(ip), 3000);//port d'écoute 3000
            //169.254.94.156

            //connexion serveur
            try
            {
                this.client.Connect(serverEndPoint);
                //configure network
                this.clientStream = client.GetStream();

                //vide les donnée
                clientStream.Flush();
                //utilisait un thread pour recevoir les donnée
            }catch(Exception )
            {
                Console.WriteLine("Erreur connexion vers Serveur");
                this.Endclient();
            }
          }

        public void Envois(snake snake)
        {
           
            this.snake = snake;
            this.sender = new Thread(new ParameterizedThreadStart(Envoi));
            this.sender.Name = "Thread Envoi";
            this.sender.Start(snake);
        }

        public void Envoi(object snake)
        {
            while (true)
            {
                //permet l'envoi
                /*  ASCIIEncoding encoder = new ASCIIEncoding();
                  //buffer pour envoi
                  byte[] buffer = encoder.GetBytes(snake.nameplayer);
                  //System.Windows.Forms.MessageBox.Show("Nom de mon adversaire "+NamePlayeur);  
                  //envoie information
                  clientStream.Write(buffer, 0, buffer.Length);
                  clientStream.Flush();
                  */
                try
                {
                    MemoryStream fs = new MemoryStream();

                    IFormatter formatter = new BinaryFormatter();
                    //Console.WriteLine("Score envoyer :" + this.snake.Score);
                   // if(this.snake.Envoyer)
                    {
                        formatter.Serialize(clientStream, this.snake);
                    }
                }
                catch (Exception)
                {
                    Console.WriteLine("Erreur Envoie Vers Serveur");
                    this.Endclient();
                }
            }
        }

        public void Reception()
        {
            this.Listen = new Thread(new ThreadStart(Receptions));
            this.Listen.Name = "Thread Listen";
            this.Listen.Start();
            
        }

        private void Receptions()
        {
          //  Console.Write("ICCCCCCCIIIIIIIIIIIIIIIIIIIIIIIIIIIIII");
            while(true)
            {
                snake snakeTempo = new snake();
                try
                {
                    this.mu.WaitOne();
                    IFormatter formatter = new BinaryFormatter();
                   // Console.WriteLine("Ici= ");
                    snakeTempo = (snake)formatter.Deserialize(clientStream);
                    this.snakeRecu = snakeTempo;
                    this.NameOtherPlayer = this.snakeRecu.nameplayer;
                    //        this.mutexsynchro.ReleaseMutex();
                    this.recu = true;
                    //Console.WriteLine("Taille Recu = " + this.snakeRecu.Size);
                    //Console.WriteLine("Score recu =" + this.snakeRecu.Score);
                    this.mu.ReleaseMutex();
                }
                catch (Exception)
                {
                    Console.WriteLine("Erreur Reception Vers Serveur");
                    this.Endclient();
                }
                //ne dois pas être fait tant que la connexion n'est pas réaliser ..
                //this.Envoi(snake);
               // Console.WriteLine("Nom recu = " + this.snakeRecu.nameplayer);

                /*
                int bytesRead = 0;

                //this.seri.deserialization(this.clientStream);

                //Console.Write("ICCCCCCCIIIIIIIIIIIIIIIIIIIIIIIIIIIIII");
                byte[] message = new byte[4096];
                bytesRead = clientStream.Read(message, 0, 4096);
                ASCIIEncoding encoder = new ASCIIEncoding();
              //  this.seri.deserialization(this.clientStream);
                this.NameOtherPlayer = encoder.GetString(message, 0, bytesRead);
                Console.WriteLine("Client Nom de mon adversaire " + this.NameOtherPlayer);
                //System.Windows.Forms.MessageBox.Show("Client Nom de mon adversaire " + encoder.GetString(message, 0, bytesRead));
                this.recu = true;
                clientStream.Flush();
                 * */

            }  

        }

        public void Endclient()
        {
            this.Listen.Abort();
            this.sender.Abort();
            this.client.Close();
            this.clientStream.Close();
        }
    }
}
